Diese Dokument beschreibt die notwendigen Schritte, um die Delphi Komponente 
TTreeView so zu erweitern, da:

a) deren Verhalten zur Entwurfszeit genauso ist, wie zur Laufzeit,
b) Drag'n Drop zur Entwurfszeit mglich wird und
c) die Verwendung verschiedener Farben und Fonts fr verschiedene Knoten mglich wird.

So ntzlich TTreeView auch ist, Borland hat einige sehr wichtige Eigenschaften einfach nicht
implementiert und so mu sich der Nutzer selbst behelfen. Aber das ist (wenn man es einmal weis) 
garnicht sonderlich schwierig. Die beigefgten Units verdeutlichen die hier beschriebenen 
Ergnzungen.

Zu a) 
Damit TTreeView (und ebenso alle anderen Komponenten, die das sonst nicht tun) berhaupt Nachrichten
zur Entwurfszeit (kurz EZ) erhalten knnen, mu man die CM_DESIGNHITTEST Nachricht abfangen und
eine geeignete Antwort zurckgeben. Soll eine Komponente EZ-Nachrichten akzeptieren, dann gibt man 
im Feld Message.Result den Wert 1 zurck. Man sollte allerdings nicht global alle Nachrichten 
akzeptieren, da sonst das normale EZ Handling nicht mehr funktioniert (z.B. Verschieben auf dem 
Formular). Also verknpft man die Antwort am besten mit einer Bedingung (z.B. ob sich ein Knoten 
unter der Maus befindet), wie im Sourcecode gezeigt. 
Damit auch das Scrollen funktioniert, mu eine weitere Nachricht abgefangen werden: WM_NCHITTEST.
Diese Nachricht erhlt die Komponente gleich nachdem festgestellt wurde, da sie berhaupt welche 
empfangen darf (ber CM_DESIGNHITTEST). Um das gleiche Verhalten wie zur Laufzeit herzustellen, darf 
die Nachricht WM_NCHITTEST nicht ber die vererbten Handler von WinControl und dergleichen laufen, 
sondern mu direkt an den Standardhandler weitergegeben werden (siehe Sourcode).

Zu b)
Prinzipiell sollte Drag'n Drop nach der Behandlung gem Punkt a) funktionieren, aber Borland hat
noch einen weiteren Fallstrick eingebaut. Die Maus-Nachrichten whrend einer Drag'n Drop Aktion
werden an ein verstecktes Fenster geleitet, da seinerseits erweiterte Nachrichten an das Control
versendet (drag over, drag enter usw.). Diese werden als CM_DRAG Nachricht verschickt und whrend
der EZ innerhalb der VCL aufgehalten. Fr uns bedeutet das, da wir CM_DRAG in der Window Prozedur
auf seinen normalen Weg schicken mssen, bevor die VCL das verhindert. Dies geschieht durch:
	IF Message.Msg = CM_DRAG THEN Dispatch(Message) ELSE INHERITED WndProc(Message);
in unserer (berschriebenen) WndProc.

Zu c) 
Das Fehlen der Mglichkeit TTreeView (und alle anderen common controls) seinen eigenen Bedrfnissen 
anzupassen, trifft Borland nur bedingt, da diese Mglichkeit erst seit kurzer Zeit verfgbar ist 
(ich vermute seit dem IE 3.0, da kam eine neue CommCtrl.DLL mit). Es geht dabei nicht darum, das
Control komplett selbst zu zeichnen (das whre viel zu aufwendig), sondern nur bestimmte Dinge zu
ndern, wie die Schriftfarbe, die Schriftart oder auch ein anderer Hintergrund (wie die Button-
Leiste im IE 3). Das Prinzip funktioniert folgendermaen:

- Jedes der common controls sendet whrend eines Repaints an sein Elternfenster eine WM_NOTIFY 
Nachricht mit der Kennzeichnung NM_CUSTOMDRAW im Feld Message.NMHdr^.code (siehe auch Deklaration 
des Message-Records TWMNotify). Note: Da viele Controls Nachrichten an ihre Elternfenster versenden, 
diese aber unter Delphi nicht vorherbestimmt und auerdem beliebig kombinierbar sind, lt Delphi
alle Fensterkomponenten bestimmte Meldungen als Komponenten-Nachrichten (CM_) oder -Notifkationen
(CN_) and das rufende Kindfenster zurcksenden. Dadurch kann dieses Kindfenster die Behandlung selbst
durchfhren. Das gilt auch fr WM_NOTIFY (von Windows versendet), das als CN_NOTIFY zurckkommt (vom 
Elternfenster versendet).

- Das Control kann diese Nachricht behandeln und damit sein (Standard) Aussehen verndern. Genaueres
dazu ist unter der unten angegebenen Adresse zu finden. In unserem Fall will TTreeView die Farben 
oder Fonts seine Knoten ndern (sagen wir in Abhngigkeit des Levels). Also gibt er auf den Code 
CDDS_PREPAINT (kommt als erster beim Repaint) den Code Message.Result:=CDRF_NOTIFYITEMDRAW; zurck 
und teilt damit Windows seinen Wunsch mit.

- Nun erhlt TTreeView beim Zeichnen jedes Knotens eine CN_NOTIFY Message mit dem Code CDDS_ITEMPREPAINT.
Beim Empfang erhlt der Messagehandler auerdem einen gltigen Device Context, dessen Eigenschaften nun
verndert werden knnen, z.B. indem man einen neuen Font hineinselektiert:
	SelectObject(nmcd.hdc,TempFont.Handle);
Danach mu man diese nderung kennzeichnen mit:
	Message.Result:=CDRF_NEWFONT;
Ist nur die Farbe gendert worden, ist dies nicht ntig und wir geben:
	Message.Result:=CDRF_DODEFAULT;
zurck.

Und das war's dann auch schon fr diesen Fall. Mehr Einzelheiten zur ganzen Problematik erhlt man 
ber MSDN Online (www.microsoft.com/msdn, die Mitgliedschaft ist kostenlos). 
Zu finden sind die entsprechenden Dokumente ber den Pfad:

Microsoft Developer Network Online Library
+ SDK Documentation
  + Internet/Intranet/Extranet Services
    + Memphis and Windows NT 5.0 Shell Preview
      + Internet Application Development
        + Application and Internet Services
          + Common Controls API
            + Custom Draw

Sieht man sich diesen Pfad genauer an, kann man leicht erraten, warum diese Informationen bisher
noch nicht sehr weit verbreitet sind. brigens: Die Custom Draw Technik funktioniert schon jetzt, 
auch wenn die Dokumente unter Windows 5.0 und Internet stehen.

Und nun, viel Spa beim Programmieren!

Dipl.-Ing. Mike Lischke
